package com.xy.smartsms.util;

import android.content.Context;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import static java.util.concurrent.Executors.newFixedThreadPool;

public class BitmapCallable implements Callable<Boolean> {
    private static final String TAG = BitmapCallable.class.getSimpleName();
    private static final int IMAGE_WIDTH = 200;
    private static final int IMAGE_HIGHT = 200;

    private Context context = null;
    private String url = null;
    private OutputStream outputStream = null;
    private ExecutorService executor = newFixedThreadPool(1);
    private Map<String, String> extend = null;

    public BitmapCallable(Context context) {
        this.context = context;
    }

    public void setParam(String url, OutputStream os) {
        this.url = url;
        this.outputStream = os;
    }


    public synchronized HashMap<String, String> getExtend() {
        if (extend == null) {
            extend = new HashMap<String, String>();
            extend.put("syn", "true");
        }

        return (HashMap<String, String>) extend;
    }

    // TODO more robust
    @Override
    public Boolean call() throws Exception {
        HttpURLConnection urlConnection = null;
        BufferedOutputStream out = null;
        BufferedInputStream in = null;

        try {
            final URL url = new URL(this.url);
            urlConnection = (HttpURLConnection) url.openConnection();
            in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
            out = new BufferedOutputStream(this.outputStream, 8 * 1024);

            int b;
            while ((b = in.read()) != -1) {
                out.write(b);
            }

            return true;
        } catch (final IOException e) {
            Log.i(TAG, "call: ");
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }

            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (final IOException e) {
                Log.i(TAG, "call: close");
            }
        }

        return false;
    }

    public Boolean executeWithTimeout(int timeout) {
        Boolean result = false;
        Future<Boolean> future = executor.submit(this);
        try {
            result = future.get(timeout, TimeUnit.MILLISECONDS);
        } catch (Throwable t) {
            Log.e(TAG, "executeWithTimeout", t);
        }

        return result;
    }
}